using Chaotic.DataBase.DataAccess;
using Chaotic.DataBase.DBAccessLibrary.Common;
using Chaotic.DataBase.DBAccessLibrary.Model;
using System.Collections;
using System.Collections.Generic;
using System.Data;
using System.Data.Common;
using System.Text;

namespace Chaotic.DataBase.DBAccessLibrary.DBAccessLibrary;

public abstract class DBGrammar(ConnectionModel? connect)
{
	protected readonly ChDescriptionXml _xml = new();

	protected ConnectionModel? _connect = connect;

    public string SelectAll(TableEntity table)
	{
		return $"SELECT {string.Join(",", from o in table.FieldNodes
                                          orderby o.Index
            select o.IsTrans ? (string.IsNullOrEmpty(o.TransChName) ? o.TransName : (o.TransName + " AS " + o.TransChName)) : o.TransName)} FROM {table.TransName} ";
	}

	protected string TabText(string text)
	{
		return text.ToUpper().Trim() switch
		{
			"S" => "SELECT * FROM", 
			"U" => "UPDATE", 
			"D" => "DELETE FROM", 
			"DT" => DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss"), 
			_ => string.Empty, 
		};
	}

	public string GetCreateInfo(DatabaseType targetType, TableEntity entity)
	{
		StringBuilder stringBuilder = new StringBuilder();
		stringBuilder.AppendLine(GetCreateTable(targetType, entity, isAddPrimary: true));
		stringBuilder.Append(";");
		stringBuilder.Append(Environment.NewLine + Environment.NewLine);
		switch (targetType)
		{
		case DatabaseType.DB2:
			if (entity.RelationNodes.Any())
			{
				stringBuilder.Append("--添加外键信息" + Environment.NewLine);
			}
			foreach (RelationshipEntity relationNode in entity.RelationNodes)
			{
				stringBuilder.Append(string.Format("ALTER TABLE {0} " + Environment.NewLine + " ADD CONSTRAINT \"{1}\" FOREIGN KEY " + Environment.NewLine + " (\"{2}\") REFERENCES {3} (\"{4}\")" + Environment.NewLine + " ON DELETE {5} " + Environment.NewLine + " ON UPDATE {6} " + Environment.NewLine + " ENFORCED ENABLE QUERY OPTIMIZATION ", entity.TransName, relationNode.RefKeyName, relationNode.ColumnName, relationNode.RelationTableName, relationNode.RelationColumnName, relationNode.IsCascadingDelete ? "CASCADE" : "NO ACTION", relationNode.IsCascadingUpdate ? "CASCADE" : "NO ACTION"));
				stringBuilder.Append(";" + Environment.NewLine + Environment.NewLine);
			}
			if (entity.IndexNodes.Any())
			{
				stringBuilder.Append("--添加索引信息" + Environment.NewLine);
			}
			foreach (IndexDescriptionEntity indexNode in entity.IndexNodes)
			{
				List<string> list4 = (from IndexEntity indexEntity in indexNode.ChildNodes
					select $"\"{indexEntity.ColumnName}\" {indexEntity.Sequence}").ToList();
				if (list4.Count > 0)
				{
					if (!indexNode.IsUnique)
					{
						stringBuilder.Append(string.Format("CREATE INDEX {0} ON {1} (" + Environment.NewLine + "{2}" + Environment.NewLine + ")" + Environment.NewLine + " COMPRESS NO ALLOW REVERSE SCANS", indexNode.Name, entity.Name, string.Join("," + Environment.NewLine, list4.ToArray())));
					}
					stringBuilder.Append(";" + Environment.NewLine + Environment.NewLine);
				}
			}
			break;
		case DatabaseType.MSSQLServer:
			if (entity.RelationNodes.Any())
			{
				stringBuilder.Append("--添加外键信息" + Environment.NewLine);
			}
			foreach (RelationshipEntity relationNode2 in entity.RelationNodes)
			{
				stringBuilder.Append(string.Format("ALTER TABLE [{0}] WITH CHECK" + Environment.NewLine + " ADD CONSTRAINT [{1}] FOREIGN KEY " + Environment.NewLine + " ([{2}]) REFERENCES [{3}] ([{4}])" + Environment.NewLine + " {5} {6} " + Environment.NewLine, entity.TransName, relationNode2.RefKeyName, relationNode2.ColumnName, relationNode2.RelationTableName, relationNode2.RelationColumnName, relationNode2.IsCascadingDelete ? ("ON DELETE CASCADE " + Environment.NewLine) : "", relationNode2.IsCascadingUpdate ? ("ON UPDATE CASCADE " + Environment.NewLine) : ""));
				stringBuilder.Append(";" + Environment.NewLine + Environment.NewLine);
			}
			if (entity.IndexNodes.Any())
			{
				stringBuilder.Append("--添加索引信息" + Environment.NewLine);
			}
			foreach (IndexDescriptionEntity indexNode2 in entity.IndexNodes)
			{
				List<string> list3 = (from IndexEntity indexEntity in indexNode2.ChildNodes
					select $"[{indexEntity.ColumnName}] {indexEntity.Sequence}").ToList();
				if (list3.Count > 0 && !indexNode2.IsUnique)
				{
					stringBuilder.Append(string.Format("CREATE {0}NONCLUSTERED INDEX [{1}] ON [{2}] (" + Environment.NewLine + "{3}" + Environment.NewLine + ")" + Environment.NewLine + "WITH (PAD_INDEX  = OFF, STATISTICS_NORECOMPUTE  = OFF, SORT_IN_TEMPDB = OFF, IGNORE_DUP_KEY = OFF, DROP_EXISTING = OFF, ONLINE = OFF, ALLOW_ROW_LOCKS  = ON, ALLOW_PAGE_LOCKS  = ON) " + Environment.NewLine + "ON [PRIMARY]", indexNode2.IsUnique ? "UNIQUE " : "", indexNode2.Name, entity.Name, string.Join("," + Environment.NewLine, list3.ToArray())));
					stringBuilder.Append(";" + Environment.NewLine + Environment.NewLine);
				}
			}
			break;
		case DatabaseType.Oracle:
			if (entity.RelationNodes.Any())
			{
				stringBuilder.Append("--添加外键信息" + Environment.NewLine);
			}
			foreach (IGrouping<string, RelationshipEntity> item in from o in entity.RelationNodes
				group o by o.RefKeyName)
			{
				List<RelationshipEntity> list = item.ToList();
				stringBuilder.Append(string.Format("ALTER TABLE {0} " + Environment.NewLine + " ADD CONSTRAINT {1} FOREIGN KEY " + Environment.NewLine + " ({2}) REFERENCES {3} ({4})" + Environment.NewLine + " {5} {6} " + Environment.NewLine, entity.TransName, item.Key, string.Join(",", list.Select((o) => o.ColumnName).ToArray()), list[0].RelationTableName, string.Join(",", list.Select((o) => o.RelationColumnName).ToArray()), list[0].IsCascadingDelete ? ("ON DELETE CASCADE " + Environment.NewLine) : "", list[0].IsCascadingUpdate ? ("ON UPDATE CASCADE " + Environment.NewLine) : ""));
				stringBuilder.Append(";" + Environment.NewLine + Environment.NewLine);
			}
			if (entity.IndexNodes.Any())
			{
				stringBuilder.Append("--添加索引信息" + Environment.NewLine);
			}
			foreach (IndexDescriptionEntity indexNode3 in entity.IndexNodes)
			{
				List<string> list2 = (from IndexEntity indexEntity in indexNode3.ChildNodes
					select $"{indexEntity.ColumnName} {indexEntity.Sequence}").ToList();
				if (list2.Count > 0 && !indexNode3.IsUnique)
				{
					stringBuilder.Append(string.Format("CREATE {0} INDEX {1} ON {2}(" + Environment.NewLine + "{3}" + Environment.NewLine + ")", indexNode3.IsUnique ? "UNIQUE " : "", indexNode3.Name, entity.Name, string.Join("," + Environment.NewLine, list2.ToArray())));
					stringBuilder.Append(";" + Environment.NewLine + Environment.NewLine);
				}
			}
			break;
		}
		return stringBuilder.ToString();
	}

	protected string GetCreateTable(DatabaseType targetType, TableEntity entity, bool isAddPrimary)
	{
		StringBuilder stringBuilder = new StringBuilder();
		stringBuilder.AppendLine($"CREATE TABLE {entity.TransName} (");
		string[] source = ["VARCHAR", "CHAR", "VARCHAR2", "NVARCHAR"];
		string[] source2 = ["DECIMAL", "NUMBER", "BLOB", "CLOB"];
		List<string?> list = new List<string?>();
		List<FieldEntity> list2 = entity.FieldNodes.OrderBy((o) => o.Index).ToList();
		for (int i = 0; i < list2.Count; i++)
		{
			FieldEntity fieldEntity = list2[i];
            if (fieldEntity.IsPrimaryKey)
			{
				list.Add(fieldEntity.TransName);
			}
			string? transName = fieldEntity.TransName;
			string text = (fieldEntity.IsNull ? "" : "NOT NULL");
			string? transChName = fieldEntity.TransChName;
			if (source.Contains(fieldEntity.TypeName?.ToUpper()))
			{
				stringBuilder.Append(
                    $"   {transName?.PadRight(30, ' ')}{(fieldEntity.TypeName + "(" + fieldEntity.Length + ")").PadRight(20, ' ')}{text.PadLeft(10, ' ')}");
			}
			else
			{
				string text2 = string.Empty;
				if (source2.Contains(fieldEntity.TypeName?.ToUpper()))
				{
					text2 = "(" + fieldEntity.Length;
					if (!string.IsNullOrEmpty(fieldEntity.Scale) && fieldEntity.Scale != "0")
					{
						text2 = text2 + "," + fieldEntity.Scale;
					}
					text2 += ")";
				}
				stringBuilder.Append($"   {transName?.PadRight(30, ' ')}{(fieldEntity.TypeName + text2).PadRight(20, ' ')}{text.PadLeft(10, ' ')}");
			}
			if (!string.IsNullOrEmpty(fieldEntity.DefaultValue))
			{
				if (targetType == DatabaseType.DB2)
				{
					stringBuilder.Append(" WITH DEFAULT " + fieldEntity.DefaultValue);
				}
				else
				{
					stringBuilder.Append(" DEFAULT " + fieldEntity.DefaultValue);
				}
			}
			bool flag = i == entity.FieldNodes.Count() - 1;
			if (string.IsNullOrEmpty(transChName))
			{
				if (!flag || (isAddPrimary && list.Count != 0))
				{
					stringBuilder.AppendLine(",");
				}
			}
			else if (flag && (!isAddPrimary || list.Count == 0))
			{
				stringBuilder.AppendLine("          --" + transChName);
			}
			else
			{
				stringBuilder.AppendLine(",         --" + transChName);
			}
		}
		if (isAddPrimary && list.Count > 0)
		{
			stringBuilder.AppendLine($"   primary key({string.Join(",", list.ToArray())})");
		}
		stringBuilder.AppendLine(Environment.NewLine + ")");
		return stringBuilder.ToString();
	}

	public string GetDataSetToInsertSql(string sql, DataSet? ds, Func<string, bool?> dbTypeAction, out string tableName)
	{
		tableName = string.Empty;
		if (ds == null || ds.Tables.Count == 0)
		{
			return string.Empty;
		}
		if (string.IsNullOrEmpty(sql))
		{
			return string.Empty;
		}
		sql = sql.Replace(Environment.NewLine, "");
		string[] array = sql.Split([" "], StringSplitOptions.RemoveEmptyEntries);
		for (int i = 0; i < array.Length; i++)
		{
			if (array[i].ToLower() == "from")
			{
				tableName = array[i + 1].Trim();
				break;
			}
		}
		string text = string.Empty;
		if (ds.Tables[0].Columns.Cast<DataColumn>().Any((c) => c.DataType == typeof(DateTime)))
		{
			bool? flag = dbTypeAction("由于导出列中包含时间类型，请选择导出数据库的格式。\r\n（是：DB2 否：ORACLE 取消：SQLSERVER）");
			text = ((flag == true) ? "DB2" : ((flag != false) ? "SQLSERVER" : "ORACLE"));
		}
		if (text == string.Empty && ds.Tables[0].Columns.Cast<DataColumn>().Any((c) => c.DataType == typeof(bool)))
		{
			bool? flag2 = dbTypeAction("由于导出列中包含布尔类型，请选择导出数据库的格式。\r\n（是：DB2，ORACLE 否：SQLSERVER）");
			if (flag2 == true)
			{
				text = "DB2";
			}
			else if (flag2 == false)
			{
				text = "SQLSERVER";
			}
		}
		StringBuilder stringBuilder = new StringBuilder();
		foreach (DataRow row in ds.Tables[0].Rows)
		{
			List<string> list = new List<string>();
			List<string?> list2 = new List<string?>();
			foreach (DataColumn column in ds.Tables[0].Columns)
			{
				if (column.ColumnName == "Dynamic_ID" || column.ColumnName == "ROWNUMBER")
				{
					continue;
				}
				list.Add($"[{column.ColumnName}]");
				if (column.DataType == typeof(string))
                {//防止有关键字 所以增加 []
                    list2.Add(string.Concat("'", row[column.ColumnName], "'"));
                }
				else if (column.DataType == typeof(bool))
                {
                    if (text == "DB2")
                    {
                        list2.Add(((bool)row[column.ColumnName]) ? "1" : "0");
                    }
                    else
                    {
                        list2.Add(string.Concat("'", row[column.ColumnName], "'"));
                    }
                }
				else if (column.DataType == typeof(DateTime))
				{
					if (string.IsNullOrEmpty(row[column.ColumnName].ToString()))
					{
						list2.Add("Null");
						continue;
					}
					DateTime dateTime = Convert.ToDateTime(row[column.ColumnName].ToString());
					if (text == "DB2")
					{
						list2.Add($"timestamp('{dateTime:yyyy-MM-dd-HH.mm.ss}')");
					}
					else if (text == "ORACLE")
					{
						list2.Add($"to_date('{dateTime:yyyy-MM-dd HH:mm:ss}','yyyy-mm-dd hh24:mi:ss')");
					}
					else
					{
						list2.Add("'" + dateTime.ToString("yyyy-MM-dd HH:mm:ss") + "'");
					}
				}
				else if (row[column.ColumnName].ToString() == string.Empty)
				{
					list2.Add("0");
				}
				else
				{
					list2.Add(row[column.ColumnName].ToString());
				}
			}
			stringBuilder.AppendLine(
                $"insert into [{tableName}]({string.Join(",", list.ToArray())}) values({string.Join(",", list2.ToArray())});");
		}
		return stringBuilder.ToString();
	}

	public virtual void SaveChange(TableEntity table, IList<FieldEntity?> newList, Action<string, int> WriteLog, Func<string, bool> showMsg)
	{
		try
		{
			List<FieldEntity?> list = new List<FieldEntity?>();
			List<FieldEntity?> list2 = new List<FieldEntity?>();
			bool flag = false;
			foreach (FieldEntity? fieldEntity in newList)
			{
				if(fieldEntity == null)
				{
					continue;
                }
                if (fieldEntity.Status == EditStatus.Delete)
				{
					foreach (string? item in fieldEntity.RemoveColumnSql)
					{
                        if (item != null)
                        {
                            WriteLog(item, 0);
                            DBOperatorFactory.GetOperator.ExecNonQuery(item, SysCache.DBConnection, null,
                                TransactionType.Transaction);
                        }
                    }
					list.Add(fieldEntity);
				}
				else if (fieldEntity.Status == EditStatus.Add)
				{
					string? addColumnSql = fieldEntity.AddColumnSql;
                    if (addColumnSql != null)
                    {
                        WriteLog(addColumnSql, 0);
                        DBOperatorFactory.GetOperator.ExecNonQuery(addColumnSql, SysCache.DBConnection, null,
                            TransactionType.Transaction);
                    }

                    list2.Add(fieldEntity);
				}
				else if (fieldEntity.Status == EditStatus.Modify)
				{
					foreach (string? item2 in DBOperatorFactory.GetGrammar(SysCache.DBConnection)?.EditColumn(fieldEntity)!)
					{
                        if (item2 != null)
                        {
                            WriteLog(item2, 0);
                            DBOperatorFactory.GetOperator.ExecNonQuery(item2, SysCache.DBConnection, null,
                                TransactionType.Transaction);
                        }
                    }
				}
				if (!flag && fieldEntity.IsChange((o) => o.IsPrimaryKey))
				{
					flag = true;
				}
				DBOperatorFactory.GetOperator.SaveDescription(table, fieldEntity, string.Empty, isnewTable: false, TransactionType.Transaction);
			}
			if (flag)
			{
				foreach (string? item3 in table.AddPrimarySql)
				{
                    if (item3 != null)
                    {
                        WriteLog(item3, 0);
                        DBOperatorFactory.GetOperator.ExecNonQuery(item3, SysCache.DBConnection, null,
                            TransactionType.Transaction);
                    }
                }
			}
			DBOperatorFactory.GetOperator.CommitTransaction(SysCache.DBConnection);
			table.Commit();
			list.ForEach(delegate(FieldEntity? o)
			{
				newList.Remove(o);
				table.Remove(o);
			});
			list2.ForEach(delegate(FieldEntity? o)
			{
				if (o != null)
				{
					o.Status = EditStatus.UnChange;
					table.Add(o);
				}
			});
			foreach (FieldEntity? item4 in list)
			{
				newList.Remove(item4);
			}
			WriteLog("提交成功", 0);
		}
		catch (Exception ex)
		{
			DBOperatorFactory.GetOperator.RollbackTransaction(SysCache.DBConnection);
			table.RollBack();
			WriteLog("回滚成功.异常详细:" + ex.Message, 1);
			throw;
		}
	}

	public List<ExecSqlModel> SubmitDataChange(DataSet ds, string tableName)
	{
		if (ds == null || ds.GetChanges() == null)
		{
			throw new Exception("没有可修改的数据");
		}
        List<ExecSqlModel> execSqlModels = new List<ExecSqlModel>();

        TableEntity? tableEntity = SysCache.TableList.FirstOrDefault(o => o.Name?.ToLower() == tableName.ToLower());
		if (tableEntity == null)
			return execSqlModels;
		 
		DataTable? changes = ds.Tables[0].GetChanges();
		if (changes?.Rows != null)
			foreach (DataRow row in changes.Rows)
			{
				switch (row.RowState)
				{
					case DataRowState.Added:
						{
							List<string> list2 = new List<string>();
                            List < DBParam > param2 = new List<DBParam>();
                            foreach (DataColumn column in changes.Columns)
							{
								list2.Add($"[{column.ColumnName}]");
                                param2.Add(new DBParam
								{
									Name = "@" + column.ColumnName,
									Value = row[column]
								}); 
							}

							if (param2.Count > 0)
							{
								execSqlModels.Add(new ExecSqlModel()
								{
									Sql = $"INSERT INTO {tableName}({string.Join(",", list2.ToArray())}) VALUES({string.Join(",", param2.Select(o=>o.Name).ToArray())})",
									Params = param2
								}); 
							}

							break;
						}
					case DataRowState.Modified:
						{
							List<string> list = new List<string>();
                            List<DBParam> param2 = new List<DBParam>();

                            string where = string.Empty;
                            List<FieldEntity> fieldEntities = tableEntity.FieldNodes.Where(o => o.IsPrimaryKey).ToList();
                            if (fieldEntities.Count != 0)
							{
                                foreach (var field in fieldEntities)
                                {
                                    //判断列中是否包含主键
                                    if (string.IsNullOrEmpty(where))
                                        where = $"[{field.Name}]=@{field.Name}";
                                    else
                                        where += $" AND [{field.Name}]=@{field.Name}";
                                    param2.Add(new DBParam
                                    {
                                        Name = "@" + field.Name,
                                        Value = row[field.Name]
                                    }); 
                                }
                            }

                            foreach (DataColumn column2 in changes.Columns)
							{
								if (!row[column2, DataRowVersion.Current].Equals(row[column2, DataRowVersion.Original]))
								{
									list.Add(column2.ColumnName + "=@" + column2.ColumnName);
                                    param2.Add(new DBParam
                                    {
                                        Name = "@" + column2.ColumnName,
                                        Value = row[column2]
                                    }); 
								}
							}

							if (list.Count > 0)
							{
                                execSqlModels.Add(new ExecSqlModel()
                                {
                                    Sql = string.Format("Update [{0}] Set {1} Where {2}", tableName, string.Join(",", list.ToArray()), where),
                                    Params = param2
                                }); 
							}

							break;
						}
					case DataRowState.Deleted:
						{
							string where = string.Empty;
                            List<DBParam> param2 = new List<DBParam>();
                            List<FieldEntity> fieldEntities = tableEntity.FieldNodes.Where(o => o.IsPrimaryKey).ToList();
							if (fieldEntities.Count != 0)
							{
								foreach (var field in fieldEntities)
								{
									//判断列中是否包含主键
									if (string.IsNullOrEmpty(where))
										where = $"[{field.Name}]=@{field.Name}";
									else
										where += $" AND [{field.Name}]=@{field.Name}";

                                    param2.Add(new DBParam
                                    {
                                        Name = "@" + field.Name,
                                        Value = row[field.Name]
                                    });
                                }
                                execSqlModels.Add(new ExecSqlModel()
                                {
                                    Sql = string.Format("Delete From [{0}] Where {1}", tableName, where),
                                    Params = param2
                                });
                            } 
						}
						break;
				}
			}

		return execSqlModels;
	}

	public bool GetExecProcInfo(string sql, out string procName, out List<DBParam>? paramlist)
	{
        procName = GetProcName(sql, out var paramStr);
		paramlist = null;
		if (string.IsNullOrEmpty(procName))
		{
			return false;
		}
		string pname = procName.Trim();
        if (SysCache.ProcList != null)
        {
            ProcEntity? procEntity = SysCache.ProcList.FirstOrDefault((o) => o.Name != null && o.Name.Equals(pname, StringComparison.OrdinalIgnoreCase));
            if (procEntity == null)
            {
                throw new Exception($"存储过程[{procName}]不存在");
            }
            string[] array = paramStr.ToFilterKeyword(",").ToArray();
			if (array.Any())
			{
				paramlist = new List<DBParam>();
				if (procEntity.ChildNodes != null)
				{
					int count = procEntity.ChildNodes.Count;
					if (array.Length < count)
					{
						throw new Exception("参数数据不对应,实际参数应该是:" + count);
					}

					for (int i = 0; i < procEntity.ChildNodes.Count; i++)
					{
						if (procEntity.ChildNodes[i] is ProcParamEntity procParamEntity)
						{
							switch (procParamEntity.Status)
							{
								case "IN":
									paramlist.Add(new DBParam
									{
										Name = procParamEntity.Name,
										Value = ConverProcTypeValue(array[i], procParamEntity.TypeName),
										ParamType = 1,
										TypeName = procParamEntity.TypeName
									});
									break;
								case "OUT":
									paramlist.Add(new DBParam
									{
										Name = procParamEntity.Name,
										ParamType = 2,
										TypeName = procParamEntity.TypeName,
										Value = "?"
									});
									break;
								case "INOUT":
									paramlist.Add(new DBParam
									{
										Name = procParamEntity.Name,
										Value = ConverProcTypeValue(array[i], procParamEntity.TypeName),
										ParamType = 3,
										TypeName = procParamEntity.TypeName
									});
									break;
								default:
									paramlist.Add(new DBParam
									{
										Name = procParamEntity.Name,
										Value = ConverProcTypeValue(array[i], procParamEntity.TypeName),
										ParamType = 6,
										TypeName = procParamEntity.TypeName
									});
									break;
							}
						}
					}
				}
            }
        }

        return true;
	}

	protected virtual string GetProcName(string sql, out string paramStr)
	{
		paramStr = string.Empty;
		if (sql.StartsWith("EXEC ", StringComparison.CurrentCultureIgnoreCase))
		{
			int num = sql.IndexOf("EXEC ", StringComparison.CurrentCultureIgnoreCase) + 5;
			int num2 = sql.IndexOf("(", StringComparison.Ordinal);
			paramStr = sql.Substring(num2 + 1, sql.LastIndexOf(")", StringComparison.Ordinal) - num2 - 1);
			return sql.Substring(num, num2 - num);
		}
		return string.Empty;
	}

	protected virtual object? ConverProcTypeValue(string value, string? type)
	{
		switch (type?.ToLower())
		{
		case "varchar":
		case "varchar2":
		case "nvarchar":
		case "char":
		case "text":
			return value.Trim('\'');
		case "decimal":
		case "money":
			return Convert.ToDecimal(value);
		case "double":
		case "number":
			return Convert.ToDouble(value);
		case "Float":
			return float.Parse(value);
		case "integer":
		case "int32":
		case "int16":
			return Convert.ToInt32(value);
		case "date":
		case "time":
		case "timestamp":
		case "datetime":
		case "dbtimestamp":
			return Convert.ToDateTime(value.Trim('\''));
		default:
			return null;
		}
	}
	 

    protected virtual string? GetTypeFilter(FieldEntity? field, string sql)
    {
        string? text = field.TypeName;
        int.TryParse(field.Length, out var result);
        string? text2 = field.Length;
        string text3 = field.TypeName.ToUpper();
        if (text3 == "VARCHAR2" || text3 == "VARCHAR")
        {
            text = "VARCHAR";
            text2 = "(" + field.Length + ")";
        }
        if ((text3 == "NUMBER" && result < 9) || text3 == "INT")
        {
            text = "INT";
            text2 = "";
        }
        else if (text3 == "NUMBER" && result >= 9)
        {
            text = "DECIMAL";
            text2 = "(18,2)";
        }
        if (text3 == "TIMESTAMP" || text3 == "DATE")
        {
            text2 = "";
        }
        if (!field.IsNull)
        {
            sql += " Not Null";
        }
        return string.Format(sql, field.TableName, field.Name, text, text2);
    }

    public virtual string GetChTableSql
    {
        get
        {
            if (string.IsNullOrEmpty(_xml.ChDescription))
            {
                return "SELECT TABLENAME,CHINESETABLENAME as CHINATABLENAME,FIELDNAME as COLUMNNAME,CHINESENAME as CHINACOLUMNNAME FROM T_FIELD_DICTIONARY order by TABLENAME";
            }
            return _xml.ChDescription;
        }
    }

    public string? AddColumn(FieldEntity? field)
    {
        string text = "ALTER TABLE [{0}] ADD {1} {2}{3}";
        if (!field.IsNull)
        {
            text += " Not Null";
        }
        if (!string.IsNullOrEmpty(field.DefaultValue))
        {
            text = text + " DEFAULT " + field.DefaultValue;
        }
        return GetTypeFilter(field, text);
    }

    public virtual IEnumerable<string?> EditColumn(FieldEntity? field)
    {
        List<string?> list = new List<string?>();
        string text = "ALTER TABLE {0} MODIFY {1} {2}{3}";
        if (field.IsChange(o => o.IsNull))
        {
            text = ((!field.IsNull) ? (text + " Not Null") : (text + " Null"));
        }
        list.Add(GetTypeFilter(field, text));
        string.IsNullOrEmpty(field.DefaultValue);
        return list;
    }

    public virtual IEnumerable<string?> RemoveColumn(FieldEntity field)
    {
        List<string?> list = new List<string?>();
        list.Add($"ALTER TABLE {field.TableName} DROP COLUMN {field.TransName}");
        return list;
    }

    public IEnumerable<string?> EditPrimary(TableEntity table)
    {
        List<string?> list = new List<string?>();
        string text = table.PrimaryKeyName;
        string[] array = (from o in table.FieldNodes
            where o.IsPrimaryKey
            select o.Name).ToArray();
        if (array.Length > 0)
        {
            if (!string.IsNullOrEmpty(text))
            {
                string? item = $"alter table [{table.Name}] drop constraint {text} ";
                list.Add(item);
            }
            else
            {
                text = "PK" + array[0];
            }
            list.Add($"ALTER TABLE [{table.Name}] ADD CONSTRAINT {text} PRIMARY KEY({string.Join(",", array)})");
        }
        return list;
    }

    public string? SelectTop(TableEntity table, int count)
    {
        string format = "SELECT TOP {1} * FROM {0}";
        return string.Format(format, table.TransName, count);
    }

    public string AppendTabText(string text)
    {
        return TabText(text);
    }

    public string GetErrorInfo(string errorMsg)
    {
        return string.Empty;
    }

    public string? GetProcParamInfo(ProcEntity entity)
    {
        if (entity == null)
        {
            return string.Empty;
        }
        string arg;
        if (entity.ChildNodes.Count > 0)
        {
            List<string> list = new List<string>();
            foreach (ProcParamEntity? childNode in entity.ChildNodes)
            {
                if (childNode.Status == "IN")
                {
                    list.Add($"{Environment.NewLine}[{childNode.Name}({childNode.TypeName})]");
                }
                else
                {
                    list.Add($"{Environment.NewLine}[{childNode.Name}({childNode.TypeName})-OUT]");
                }
            }
            arg = "(" + string.Join(",", list.ToArray()) + ")";
        }
        else
        {
            arg = "()";
        }
        return $"{"EXEC"} {entity.Name}{arg}";
    }
}
